<?php
namespace avata;

/**
 * 请求Avata平台客户端类
 * 
 * @package avata
 * @author Will <gaodongchen@qq.com>
 */
class Client {
    
    /**
     * Avata平台API地址
     *
     * @var string
     */
    private string $_endpoint;

    /**
     * API Key
     *
     * @var string
     */
    private string $_api_key;

    private array $_last_query;

    /**
     * API Secret
     *
     * @var string
     */
    private string $_secret;

    function __construct(string $endpoint, string $api_key, string $secret)
    {
        $this->_endpoint = $endpoint;
        $this->_api_key = $api_key;
        $this->_secret = $secret;
    }

    public function getLastQuery(): array
    {
        return $this->_last_query;
    }

    /**
     * 执行请求
     *
     * @param Query $query
     * @return Response
     */
    public function request(Query $query): Response
    {
        $timestamp = $query->time();
        $params = $query->getParams();
        $hash = $this->hash($timestamp, $params);
        $header = $this->header($timestamp, $hash);

        $this->_last_query = [
            'query' => $query,
            'params' => $params,
            'hash' => $hash,
            'header' => $header
        ];

        $ch = curl_init();
        curl_setopt($ch, CURLOPT_URL, $this->url(
            $this->_endpoint, 
            $query->getPath(), 
            $query->build()
        ));

        if ($query->getMethod() == 'POST') {
            curl_setopt($ch, CURLOPT_POST, true);
        } else {
            if($query->isOperation())
                curl_setopt($ch, CURLOPT_CUSTOMREQUEST, $query->getMethod());
        }

        $json_body = empty($query->getBody()) ? '' : json_encode($query->getBody());
        if($query->isOperation() && $json_body) {
            curl_setopt($ch, CURLOPT_POSTFIELDS,  $json_body);
        }
        
        curl_setopt($ch, CURLOPT_HTTPHEADER, $header);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
        $response = curl_exec($ch);
        curl_close($ch);
        
        return new Response($response);
    }

    /**
     * 生成URL
     *
     * @param string $endpoint
     * @param string $path
     * @param string $query
     * @return string
     */
    private function url(string $endpoint, string $path, string $query): string
    {
        return rtrim($endpoint, '/') . '/' . ltrim($path, '/') . $query;
    }

    /**
     * Hash
     *
     * @param integer $timestamp
     * @param array $params
     * @return string
     */
    private function hash(int $timestamp, array $params): string
    {
        $hexhash = hash("sha256", "{$timestamp}" . $this->_secret);
        if (count($params) > 0) {
            // 序列化且不编码
            $s = json_encode($params, JSON_UNESCAPED_UNICODE);
            $hexhash = hash("sha256", stripcslashes($s . "{$timestamp}" . $this->_secret));
        }

        return $hexhash;
    }

    /**
     * Header
     *
     * @param string $timestamp
     * @param string $hash
     * @return array
     */
    private function header(string $timestamp, string $hash): array
    {
        return [
            "Content-Type: application/json",
            "X-Api-Key: {$this->_api_key}",
            "X-Signature: {$hash}",
            "X-Timestamp: {$timestamp}",
        ];
    }

}